package com.guiji.text2video.fastvideo.config;


import com.guiji.text2video.fastvideo.service.Impl.Text2videoPoolsStatServiceImpl;
import com.guiji.text2video.fastvideo.utils.VisiableThreadPoolTaskExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class ExecutorConfig {

    private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);

    @Value("${async.executor.thread.nlp_core_pool_size}")
    private int nlpCorePoolSize;
    @Value("${async.executor.thread.nlp_max_pool_size}")
    private int nlpMaxPoolSize;

    @Value("${async.executor.thread.tts_core_pool_size}")
    private int ttsCorePoolSize;
    @Value("${async.executor.thread.tts_max_pool_size}")
    private int ttsMaxPoolSize;

    @Value("${async.executor.thread.english_tts_core_pool_size}")
    private int englishTtsCorePoolSize;
    @Value("${async.executor.thread.english_tts_max_pool_size}")
    private int englishTtsMaxPoolSize;

    @Value("${async.executor.thread.azhi_tts_core_pool_size}")
    private int aZhiTtsCorePoolSize;
    @Value("${async.executor.thread.azhi__max_pool_size}")
    private int aZhiTtsMaxPoolSize;

    @Value("${async.executor.thread.com_core_pool_size}")
    private int comCorePoolSize;
    @Value("${async.executor.thread.com_max_pool_size}")
    private int comMaxPoolSize;

    @Value("${async.executor.thread.com_news_core_pool_size}")
    private int comNewsCorePoolSize;
    @Value("${async.executor.thread.com_news_max_pool_size}")
    private int comNewsMaxPoolSize;


    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;

    @Value("${async.executor.thread.name.NLPprefix}")
    private String nlpPrefix;

    @Value("${async.executor.thread.name.EnglishTTSPrefix}")
    private String englishTTSPrefix;

    @Value("${async.executor.thread.name.TTSPrefix}")
    private String nameTTSPrefix;

    @Value("${async.executor.thread.name.AZhiTTSPrefix}")
    private String aZhiNameTTSPrefix;

    @Value("${async.executor.thread.name.VideoComposePrefix}")
    private String nameVideoComposePrefix;

    @Value("${async.executor.thread.name.VideoNewsComposePrefix}")
    private String nameVideoNewsComposePrefix;


    @Autowired
    Text2videoPoolsStatServiceImpl poolsStat;


    @Bean(name = "asyncNLPServiceExecutor")
    public Executor asyncNLPServiceExecutor() {
        logger.info("start asyncNLPServiceExecutor");
        return newExecutor(nlpCorePoolSize,nlpMaxPoolSize,queueCapacity,nlpPrefix);
    }

    @Bean(name = "asyncTTSServiceExecutor")
    public Executor asyncTTSServiceExecutor() {
        logger.info("start asyncTTSServiceExecutor");
        return newExecutor(ttsCorePoolSize,ttsMaxPoolSize,queueCapacity,nameTTSPrefix);
    }

    /**
     * @descp: 英语-tts合成
     * @param: 
     * @Author: scl
     * @Date: 2021/9/2 16:33
     */
    @Bean(name = "asyncEnglishTTSServiceExecutor")
    public Executor asyncEnglishTTSServiceExecutor() {
        logger.info("start asyncEnglishTTSServiceExecutor");
        return newExecutor(englishTtsCorePoolSize,englishTtsMaxPoolSize,queueCapacity,englishTTSPrefix);
    }
    
    /**
     * @descp: 硅基tts服务线程池
     * @param:
     * @Author: scl
     * @Date: 2021/9/2 16:01
     */
    @Bean(name = "guiJiTTSServiceExecutor")
    public Executor guiJiTTSServiceExecutor() {
        logger.info("start guiJiTTSServiceExecutor");
        return newExecutor(aZhiTtsCorePoolSize,aZhiTtsMaxPoolSize,queueCapacity,aZhiNameTTSPrefix);
    }

    /**
     * @descp: 合成服务线程池
     * @param: 
     * @Author: scl
     * @Date: 2021/9/2 16:01
     */
    @Bean(name = "asyncComposeVideoServiceExecutor")
    public Executor asyncComPoseVideoServiceExecutor() {
        logger.info("start asyncComposeVideoServiceExecutor");
        return newExecutor(comCorePoolSize,comMaxPoolSize,queueCapacity,nameVideoComposePrefix);
    }

    @Bean(name = "asyncComposeVideoNewsServiceExecutor")
    public Executor asyncComposeVideoNewsServiceExecutor() {
        logger.info("start asyncComposeVideoNewsServiceExecutor");
        return newExecutor(comNewsCorePoolSize,comNewsMaxPoolSize,queueCapacity,nameVideoNewsComposePrefix);
    }

    private Executor newExecutor(int setCorePoolSize,int setMaxPoolSize,int setQueueCapacity,String setThreadNamePrefix){
        ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor(poolsStat);
        //配置核心线程数
        executor.setCorePoolSize(setCorePoolSize);
        //配置最大线程数
        executor.setMaxPoolSize(setMaxPoolSize);
        //配置队列大小
        executor.setQueueCapacity(setQueueCapacity);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix(setThreadNamePrefix);
        //当pool已经达到max size的时候，拒绝规则
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }

}